/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package loja.dao;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import loja.dao.exceptions.BuscaException;
import loja.dao.exceptions.ImpossivelAtualizarException;
import loja.dao.exceptions.ImpossivelCriarException;
import loja.dao.exceptions.ImpossivelDeletarException;
import loja.dominio.Cliente;

/**
 *
 * @author Rodrigo
 */
public class ClienteDao extends AbstractGenericDao<Cliente> {

    @Override
    public void criar(Cliente cliente) throws ImpossivelCriarException {
        String sql = "insert into cliente ( nome, endereco, nascimento , cpf, email) values (?,?,?,?,?)";
        PreparedStatement stmt = null;

        try {
            iniciarTransacao();
            stmt = getConexao().prepareStatement(sql);
            stmt.setString(1, cliente.getNome());
            stmt.setString(2, cliente.getEndereco());
            stmt.setString(3, cliente.getNascimento());
            stmt.setString(4, cliente.getCpf());
            stmt.setString(5, cliente.getEmail());
            stmt.execute();
            comitarTransacao();
            JOptionPane.showMessageDialog(null, "Registro salvo com SUCESSO!!!");
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new ImpossivelCriarException("Não foi possível criar um novo cliente.");
        } finally {
            closeStatement(stmt);
        }
    }

    @Override
    public void atualizar(Cliente cliente) throws ImpossivelAtualizarException {
        String sql = "update cliente set nome=?, endereco=?, nascimento=?, cpf=?, email=? where idcliente=?";
        PreparedStatement stmt = null;

        try {
            iniciarTransacao();
            stmt = getConexao().prepareStatement(sql);
            stmt.setString(1, cliente.getNome());
            stmt.setString(2, cliente.getEndereco());
            stmt.setString(3, cliente.getNascimento());
            stmt.setString(4, cliente.getCpf());
            stmt.setString(5, cliente.getEmail());
            stmt.setLong(6, cliente.getId());
            stmt.execute();
            comitarTransacao();
            JOptionPane.showMessageDialog(null, "Registro alterado com SUCESSO!!!");
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new ImpossivelAtualizarException("Não foi possível atualizar o cliente.");
        } finally {
            closeStatement(stmt);
        }
    }

    @Override
    public void deletar(Cliente cliente) throws ImpossivelDeletarException {
        String sql = "delete from cliente where idcliente=?";
        PreparedStatement stmt = null;

        try {
            iniciarTransacao();
            stmt = getConexao().prepareStatement(sql);
            stmt.setLong(1, cliente.getId());
            stmt.execute();
            comitarTransacao();
            JOptionPane.showMessageDialog(null, "Registro excluido com SUCESSO!!!");
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new ImpossivelDeletarException("Não foi possível atualizar o cliente.");
        } finally {
            closeStatement(stmt);
        }
    }

    @Override
    public Cliente buscar(Long id) throws BuscaException {
        String sql = "select * from cliente where idcliente=?";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Cliente cliente = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            stmt.setLong(1, id);
            rs = stmt.executeQuery();
            while (rs.next()) {
                cliente = construirCliente(rs);
            }
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new BuscaException("Não foi possível buscar o cliente.");
        }
        return cliente;
    }

    @Override
    public List<Cliente> buscarTodos() throws BuscaException {
        String sql = "select * from cliente";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<Cliente> clientes = null;
        Cliente cliente = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            rs = stmt.executeQuery();
            clientes = new ArrayList<Cliente>();
            while (rs.next()) {
                cliente = construirCliente(rs);
                clientes.add(cliente);
            }
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new BuscaException("Não foi possível buscar os Clientes.");
        }
        return clientes;
    }

    public List<Cliente> buscarTodos(String nome) throws BuscaException {
        String sql = "select * from cliente where nome like ?";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<Cliente> clientes = null;
        Cliente cliente = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            stmt.setString(1, "%" + nome + "%");
            rs = stmt.executeQuery();
            clientes = new ArrayList<Cliente>();
            while (rs.next()) {
                cliente = construirCliente(rs);
                clientes.add(cliente);
            }
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new BuscaException("Não foi possível buscar o cliente.");
        }
        return clientes;
    }

    public List<Cliente> buscarPorDescricao(String descricao) throws BuscaException {
        String sql = "select * from cliente where nome like ?";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<Cliente> clientes = null;
        Cliente cliente = null;
        try {
            stmt = getConexao().prepareStatement(sql);
            stmt.setString(1, "%" + descricao + "%");
            rs = stmt.executeQuery();

            clientes = new ArrayList<Cliente>();

            while (rs.next()) {
                cliente = construirCliente(rs);
                clientes.add(cliente);
            }
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new BuscaException("Não foi possível buscar os Clientes.");
        }
        return clientes;
    }

    @Override
    public long contar() throws BuscaException {
        String sql = "select count(*) from cliente";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Long total = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            rs = stmt.executeQuery();
            while (rs.next()) {
                total = rs.getLong(1);
            }
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new BuscaException("Não foi possível contar clientes.");
        }
        return total;
    }

    public Cliente buscarPorCpf(String cpf) throws BuscaException {

        String sql = "select * from cliente where cpf=?";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Cliente cliente = null;

        try {
            stmt = getConexao().prepareStatement(sql);
            stmt.setString(1, cpf);
            rs = stmt.executeQuery();
            while (rs.next()) {
                cliente = construirCliente(rs);
            }
        } catch (SQLException ex) {
            cancelarTransacao(ex, this.getClass());
            throw new BuscaException("Não foi possível buscar o cpf do cliente.");
        }
        return cliente;
    }

    private Cliente construirCliente(ResultSet rs) throws SQLException, BuscaException {
        Cliente cliente = new Cliente();

        cliente.setId(Long.valueOf(rs.getString("idcliente")));
        cliente.setNome(rs.getString("nome"));
        cliente.setEndereco(rs.getString("endereco"));
        cliente.setNascimento(rs.getString("nascimento"));
        cliente.setCpf(rs.getString("cpf"));
        cliente.setEmail(rs.getString("email"));

        return cliente;
    }
}


